package com.randy.recyclerviews.rangecalculator;


import android.support.v7.util.DiffUtil;

import com.randy.recyclerviews.helper.Range;

import java.util.List;

/**
 * 包含 header, 数据，loadmore, footer，空Placeholder 的RangeCalculator
 * Created by xudong on 2016/12/15.
 */
@Deprecated
public class SimpleListRangeCalculator<T extends IDiffUtilHelper> implements IRangeCalculator<T> {
    protected boolean notShowEmptyFirstTime = true;
    //暂时固定
    protected final boolean hasHeader;
    protected final boolean hasFooter;

    public SimpleListRangeCalculator() {
        this(false, false);
    }

    public SimpleListRangeCalculator(boolean hasHeader, boolean hasFooter) {
        this.hasHeader = hasHeader;
        this.hasFooter = hasFooter;
    }

    public Range<Integer> headerRange, dataRange, loadMoreRange, emptyViewRange, footerRange;
    public int itemCount;

    protected List<T> cachedData;

    private T getItemByIndex(int index) {
        return cachedData != null && index >= 0 && index < cachedData.size() ?
                cachedData.get(index) : null;
    }

    @Override
    public DiffUtil.DiffResult diffRange(final IRangeCalculator<T> iRangeCal) {
        //TODO: check this cast
        final SimpleListRangeCalculator<T> cal = (SimpleListRangeCalculator<T>) iRangeCal;

        return DiffUtil.calculateDiff(new DiffUtil.Callback() {
            @Override
            public int getOldListSize() {
                return itemCount;
            }

            @Override
            public int getNewListSize() {
                return cal.itemCount;
            }

            @Override
            public boolean areItemsTheSame(int oldP, int newP) {
                if (headerRange.inRange(oldP) && cal.headerRange.inRange(newP)) {
                    return true;
                }
                if (dataRange.inRange(oldP) && cal.dataRange.inRange(newP)) {
                    T oldItem = getItemByIndex(oldP - dataRange.first),
                            newItem = cal.getItemByIndex(newP - cal.dataRange.first);
                    if (oldItem == null || newItem == null) return false;
                    return oldItem.isItemTheSame(newItem);
                }
                if (loadMoreRange.inRange(oldP) && cal.loadMoreRange.inRange(newP)) {
                    return true;
                }
                if (emptyViewRange.inRange(oldP) && cal.emptyViewRange.inRange(newP)) {
                    return true;
                }
                if (footerRange.inRange(oldP) && cal.footerRange.inRange(newP)) {
                    return true;
                }
                return false;
            }

            @Override
            public boolean areContentsTheSame(int oldP, int newP) {
                if (dataRange.inRange(oldP) && cal.dataRange.inRange(newP)) {
                    T oldItem = getItemByIndex(oldP - dataRange.first),
                            newItem = cal.getItemByIndex(newP - cal.dataRange.first);
                    if (oldItem == null || newItem == null) return false;
                    return oldItem.isContentTheSame(newItem);
                }
                return true;
            }
        });
    }

    @Override
    public boolean assignRange(IRangeCalculator<T> iRangeCal) {
        if (this.hashCode() == iRangeCal.hashCode()) return false;
        //TODO: check this cast
        final SimpleListRangeCalculator<T> cal = (SimpleListRangeCalculator<T>) iRangeCal;

        headerRange = cal.headerRange;
        dataRange = cal.dataRange;
        loadMoreRange = cal.loadMoreRange;
        emptyViewRange = cal.emptyViewRange;
        footerRange = cal.footerRange;
        itemCount = cal.itemCount;

        return true;
    }

    /**
     * 没有数据时，显示header,emptyview,footer
     *
     * @param data
     * @param hasMore
     */
    public void updateRange(List<T> data, boolean hasMore) {
        cachedData = data;

        headerRange = Range.empty(0);
        dataRange = Range.empty(0);
        loadMoreRange = Range.empty(0);
        emptyViewRange = Range.empty(0);
        footerRange = Range.empty(0);
        itemCount = 0;

        if (hasHeader) {
            headerRange = Range.create(itemCount, itemCount + 1);
            itemCount = headerRange.second;
        }
        if (data != null && data.size() > 0) {
            dataRange = Range.create(itemCount, itemCount + data.size());
            itemCount = dataRange.second;

            if (hasMore) {
                loadMoreRange = Range.create(itemCount, itemCount + 1);
                itemCount = loadMoreRange.second;
            }
        } else {
            if (notShowEmptyFirstTime) {
                notShowEmptyFirstTime = false;
            } else {
                emptyViewRange = Range.create(itemCount, itemCount + 1);
                itemCount = emptyViewRange.second;
            }
        }
        if (hasFooter) {
            footerRange = Range.create(itemCount, itemCount + 1);
            itemCount = footerRange.second;
        }
    }
}
